package com.inspectortime.webapp.inspector.reports;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;

import com.inspectortime.domain.Inspection;
import com.inspectortime.domain.InspectorCompany;
import com.inspectortime.domain.RealEstateAgent;
import com.inspectortime.domain.type.InspectionStatus;
import com.inspectortime.webapp.util.HttpSessionUtils;

public class AgentsReportController extends ReportsController {
	
	private static Log log = LogFactory.getLog(AgentsReportController.class);
	
	protected ModelAndView onSubmit(HttpServletRequest request,	HttpServletResponse response, Object command, BindException errors)
		throws Exception {
		
		ReportDateForm form = (ReportDateForm) command;
		
		InspectorCompany company = HttpSessionUtils.retrieveLoggedInCompany(request, this.getRepository());
		
		List<Inspection> inspections = company.findInspectionsBetween(form.getStartDate().getTime(), form.getEndDate().getTime());
		List<AgentsReportBean> agentBeans = new ArrayList<AgentsReportBean>();
		
		for (Inspection inspection : inspections) {
			if (inspection.getReferringAgent() != null && inspection.getInspectionStatus() != InspectionStatus.CANCELLED) {
				
				AgentsReportBean bean = null;
				
				//get agent from list, if already there
				RealEstateAgent agent = inspection.getReferringAgent();
				for (AgentsReportBean tempBean : agentBeans) {
					if (tempBean.getAgent().equals(agent)) {
						bean = tempBean;
						break;
					}
				}
				if (bean == null) {
					bean = new AgentsReportBean(agent);
					agentBeans.add(bean);
				}
				bean.addInspectionRevenue(inspection.getFinalInspectionFee());
			}
		}
		
		
		//Sort the results
		String sortBy = request.getParameter("sortBy");
		if (StringUtils.hasText(sortBy) && sortBy.equals("inspections")) {
			sortByInspections(agentBeans);
		} else {
			sortByRevenue(agentBeans);
		}
		
		ModelAndView mv = new ModelAndView(getSuccessView(), errors.getModel());
		mv.addObject("inspectorCompany", company);
		mv.addObject("agentBeans", agentBeans);
		mv.addObject("inspections", inspections);  //for testing
		return mv;
		
	}
	
	
	/**
	 * Sort by revenue descending, then by num inspections descending
	 * @param beans
	 */
	private void sortByRevenue(List<AgentsReportBean> beans) {
	
		Collections.sort(beans, new Comparator<AgentsReportBean>() {
	           public int compare(AgentsReportBean bean1, AgentsReportBean bean2) {
	        	   int result = Double.compare(bean2.getRevenue(), bean1.getRevenue());
	        	   if (result == 0) {
	        		   result = new Integer(bean2.getNumInspections()).compareTo(new Integer(bean1.getNumInspections()));
	        	   }
	        	   
	        	   return result;
	           }
	       });
	}
	
	/**
	 * Sort by num inspections descending, then by revenue descending
	 * @param beans
	 */
	private void sortByInspections(List<AgentsReportBean> beans) {
		Collections.sort(beans, new Comparator<AgentsReportBean>() {
	           public int compare(AgentsReportBean bean1, AgentsReportBean bean2) {
	        	   int result = new Integer(bean2.getNumInspections()).compareTo(new Integer(bean1.getNumInspections()));
	        	   if (result == 0) {
	        		   result = Double.compare(bean2.getRevenue(), bean1.getRevenue());
	        	   }
	        	   return result;
	           }
	       });
	}

}
